home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <math.h>
- #include "wa.h"
- #include "vec4.h"
- #include "dgflag.h"
- #include "enum.h"
- #include "color.h"
- #include "3d.h"
- #include "ooglutil.h"
- #include "discgrpP.h"
-
-
- static DiscGrp *mydg;
- static ColorA white = {1,1,1,.75};
- static DiscGrpEl grpel;
- static Transform mlist[128];
- static int (*constraintfn)();
- int check_big = 1, /* this is currently never non-zero */
- check_new = 1, /* ditto */
- have_matrices = 1,
- metric = DG_HYPERBOLIC,
- stringent = 0;
- int
- long_cnt = 0,
- same_cnt = 0,
- far_cnt = 0,
- print_cnt = 0,
- store_cnt = 0;
- static int numchunks = 1;
- static int ngens = 0;
- int debug = 0;
- static char symbollist[64];
- static void get_matrices();
-
- int
- getindex(c)
- char c;
- {
- int i;
- for (i=0; i<ngens; ++i)
- if (symbollist[i] == c) return(i);
- return(-1);
- }
-
- static
- word_to_mat(word, mat1)
- char *word;
- Transform mat1;
- {
- int length, i, index;
- /*printf("# %s\n",word); */
- TmIdentity(mat1);
-
- for (i=0; word[i] != 0; ++i)
- {
- index = getindex(word[i]);
- if (index < 0) {
- printf("Bad symbol\n");
- return;
- }
- TmConcat(mat1, mlist[index], mat1);
- }
- }
-
- static int
- is_big_and_new(DiscGrpEl *dgel)
- {
- int is_big=0, is_n = DG_CONSTRAINT_NEW;
- if (check_new) is_n = is_new(dgel->tform);
- if (is_n) {
- is_big = constraintfn(dgel);
- if (is_big & DG_CONSTRAINT_LONG) long_cnt++;
- if (is_big & DG_CONSTRAINT_PRINT) print_cnt++;
- if (is_big & DG_CONSTRAINT_STORE) store_cnt++;
- if (is_big & DG_CONSTRAINT_TOOFAR) far_cnt++;
- }
- else same_cnt++;
- return(is_big | is_n );
- }
-
-
- static int
- process(DiscGrpEl *dgel, int stacking)
- {
- Transform mat;
- register int is_ok;
-
- if (have_matrices) {
- is_ok = is_big_and_new(dgel);
- /* remember that only NEW and PRINT are required to be here */
- if (is_ok & DG_CONSTRAINT_NEW ) {
- if (!(is_ok & DG_CONSTRAINT_LONG)) {
- if (is_ok & (DG_CONSTRAINT_STORE | DG_CONSTRAINT_PRINT)) {
- if (check_new) {
- insert_mat(dgel->tform);
- /* and put it on the stack */
- if (stacking) push_new_stack(dgel->word);
- }
- if (is_ok & DG_CONSTRAINT_PRINT) enumpush(dgel);
- }
- }
- }
- }
- return(is_ok);
- }
-
- static int
- enumerate(int state, int depth, DiscGrpEl *dgel)
- {
- register int i, newstate, pval;
- Transform mat;
- char wword[64];
-
- if ( ! ((pval = process(dgel, 0)) & DG_CONSTRAINT_STORE)) return 0;
- if (pval & DG_CONSTRAINT_MAXLEN) return 0;
- if (depth > MAXDEPTH) return 0;
-
- for (i=1; i<mydg->fsa->ngens; ++i)
- {
- newstate = mydg->fsa->action[state][i];
- if ( newstate != mydg->fsa->fail)
- {
- dgel->word[depth] = mydg->fsa->genlist[i-1][0];
- dgel->word[depth+1] = 0; /* null-terminate */
- word_to_mat(dgel->word, dgel->tform);
- enumerate(newstate, depth+1, dgel);
- }
- }
- }
-
- static int
- dumb_enumerate(int depth, DiscGrpEl *dgel)
- {
- register int i, j, l, stacking;
- Transform mat;
- char *word, wword[64];
- extern char *pop_old_stack();
-
- init_stack();
- process(dgel, 1);
- for (j = 0; j < MAXDEPTH ; ++j)
- {
- make_new_old();
- /* are we interested in his descendents ? */
- while ( (word = pop_old_stack()) != NULL) {
- /* these words have length j */
- strcpy(dgel->word, word);
- for (i=0; i<ngens; ++i)
- {
- dgel->word[j] = symbollist[i];
- dgel->word[j+1] = 0; /* null-terminate */
- word_to_mat(dgel->word, dgel->tform);
- process(dgel, 1);
- }
- }
- }
- }
-
- static char emptyword[64] = "";
- /*
- * hack together an enumerate routine
- */
-
- DiscGrpElList *
- DiscGrpEnum(DiscGrp *discgrp, int (* constraint)(void) )
- {
- DiscGrpElList *enum_list = OOGLNewE(DiscGrpElList, "DiscGrpEnum");
- extern DiscGrpEl *enumgetstack();
- DiscGrpEl dgel;
-
- /* initialize the local variables */
- constraintfn = constraint;
- have_matrices = 1;
- same_cnt = 0;
- far_cnt = 0;
- print_cnt = 0;
- store_cnt = 0;
- long_cnt = 0;
- ngens = discgrp->gens->num_el;
- metric = discgrp->attributes & DG_METRIC_BITS;
- bzero(dgel.word, sizeof(dgel.word));
- dgel.attributes = discgrp->attributes;
- TmIdentity(dgel.tform);
- dgel.color = white;
- mydg = discgrp;
-
- init_out_stack();
- get_matrices();
- if (mydg->fsa) enumerate(mydg->fsa->start, 0, &dgel);
- else dumb_enumerate(0,&dgel);
-
- /* clean up the mess */
- delete_list();
-
- enum_list->num_el = enumgetsize();
- enum_list->el_list = enumgetstack();
-
- if (mydg->flag & DG_DEBUG) {
- fprintf(stderr,"%d elements printed \n",print_cnt);
- fprintf(stderr,"%d elements stored \n",store_cnt);
- fprintf(stderr,"%d elements move too far \n",far_cnt);
- fprintf(stderr,"%d elements too long \n",long_cnt);
- fprintf(stderr,"%d elements duplicates \n",same_cnt);
- }
- return(enum_list);
- }
-
-
- static void
- get_matrices()
- {
- int i;
-
- for (i=0; i<mydg->gens->num_el; ++i)
- {
- symbollist[i] = mydg->gens->el_list[i].word[0];
- TmCopy(mydg->gens->el_list[i].tform, mlist[i]);
- }
- fprintf(stderr,"%d generators read\n",i);
- }
-
-